# 默认形参
def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

print(power(2,3))
print(power(2,4))
print(power(5))

# 小坑： 定义默认参数要牢记一点：默认参数必须指向不变对象！

def add_end(L=[]):
    L.append('END')
    return L
print(add_end()) # ['END']
print(add_end()) # ['END', 'END']

# 上面的原因： Python函数在定义的时候，默认参数L的值就被计算出来了，即[]，
# 因为默认参数L也是一个变量，它指向对象[]，每次调用该函数，如果改变了L的内容，则下次调用时，默认参数的内容就变了，不再是函数定义时的[]了。

# 要修改上面的例子，我们可以用None这个不变对象来实现：
def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L
print(add_end())
print(add_end())



# 可变参数 作为一个整体
def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum
print(calc([1, 2, 3])) # 传入一个列表
print(calc((1, 3, 5, 7))) # 传入一个元组

# 可变参数 直接传入任意数量的值
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum
print(calc(1, 2, 3, 4, 5, 6))
print(calc())
# 假设这时传入的是list  可以使用  *加列表  代表收集到元组里
nums = [1, 2, 3]
print(calc(*nums))

# Python中，（*）会把接收到的参数形成一个元组，而（**）则会把接收到的参数存入一个字典
def shouji(*args):
    print(args)
shouji(1,2,3,4,5,6) # (1, 2, 3, 4, 5, 6) 是一个元组
def shouji1(**numbers):
    print(numbers)
shouji1(a=1, b=2, c=3) # {'a': 1, 'b': 2, 'c': 3} 是一个字典